package org.funtester.performance.books.chapter05.sectioin3;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.*;

/**
 * Netty-WebSocket 客户端处理器
 */
public class WebSocketIOHandler extends SimpleChannelInboundHandler<Object> {

    /**
     * WebSocket 客户端握手处理器
     */
    public WebSocketClientHandshaker handShaker;

    /**
     * 握手响应的promise,用来表示连接是否成功
     */
    public ChannelPromise handshakeFuture;

    /**
     * 构造函数
     * @param webSocketClientHandshaker
     */
    public WebSocketIOHandler(WebSocketClientHandshaker webSocketClientHandshaker) {
        this.handShaker = webSocketClientHandshaker;
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        System.out.println("handler已经被添加到ChannelPipeline中");
        handshakeFuture = ctx.newPromise();// 创建握手响应的promise
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        handShaker.handshake(ctx.channel());// 发送握手请求
        System.out.println("WebSocket 连接成功");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        ctx.close();
        System.out.println("WebSocket 连接断开");
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.out.println("WebSocket 异常 " + cause.getMessage());
        if (!handshakeFuture.isDone()) {
            handshakeFuture.setFailure(cause);
        }
        ctx.close();
    }

    /**
     * 处理WebSocket消息
     * @param ctx 上下文
     * @param msg 消息
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        Channel channel = ctx.channel();// 获取当前channel
        if (!handShaker.isHandshakeComplete()) {// 如果握手未完成
            try {
                FullHttpResponse fullHttpResponse = (FullHttpResponse) msg;// 获取握手响应
                System.out.println(fullHttpResponse);// 打印握手响应
                handShaker.finishHandshake(channel, fullHttpResponse);// 完成握手
                handshakeFuture.setSuccess();// 设置握手成功
            } catch (WebSocketHandshakeException e) {
                handshakeFuture.setFailure(e);// 设置握手失败
            }
            return;// 握手完成,不再处理
        }
        WebSocketFrame frame = (WebSocketFrame) msg;// 获取WebSocket消息
        if (frame instanceof TextWebSocketFrame) {// 如果是文本消息
            TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;// 转换为文本消息
            System.out.println("收到消息: " + textFrame.text());// 打印消息
        } else if (frame instanceof CloseWebSocketFrame) {// 如果是关闭消息
            channel.close();// 关闭channel
        }
    }

}
